﻿using System;
using System.Reflection;
using NUnit.Framework;
using RenewalProjects.Libraries.Common.Testing.Helpers;
using RenewalProjects.Libraries.Common.Testing.Interfaces;
using RenewalProjects.Libraries.Wcf.EasyProxy.CallBehaviors;
using RenewalProjects.Libraries.Wcf.EasyProxy.ChannelAllocators;
using RenewalProjects.Libraries.Wcf.EasyProxy.Tests.TestBuilders;
using RenewalProjects.Libraries.Wcf.EasyProxy.Tests.TestData;
using Rhino.Mocks;

namespace RenewalProjects.Libraries.Wcf.EasyProxy.Tests.Fixtures
{
	[TestFixture]
	public class DefultCallBehaviorFixture : IUsesRhinoMocks
	{
		#region Properties

		public MockRepository Mock { get; set; }

		#endregion

		#region Test Methods

		[Test]
		public void DefaultCallBehavior_receives_invocation_on_a_operation()
		{
			ITest testChannel = Mock.PartialMock<TestChannel>();
			testChannel.Stub(x => x.GetName()).Return("Danny");
			
			ChannelAllocatorBase<ITest> channelAllocator =
			        new ChannelAllocatorBuilder<ITest>(Mock, testChannel)
			            .ExpectAvailableChannelRetrieval()
			            .ChannelHolder(x=>x.ExpectEndCall())
			            .Build();
			
			Mock.ReplayAll();

			var methodResult = BasicExpressionHelper<ITest>.ObtainMethodAndArguments(x=>x.GetName());
			object res = new DefaultCallBehavior<ITest>(channelAllocator)
			                 .InvokeOperation(methodResult.Method, methodResult.Arguments);

			Assert.AreEqual("Danny", res);
		}

		[ExpectedException(typeof(TargetInvocationException))]
		[Test]
		public void DefaultCallBehavior_calls_dodgy_operation()
		{
			ChannelAllocatorBase<ITest> channelAllocator =
			        new ChannelAllocatorBuilder<ITest>(Mock, new TestChannel())
			            .ExpectAvailableChannelRetrieval()
			            .ChannelHolder(x=>x.ExpectAbortCall())
			            .Build();
			
			Mock.ReplayAll();

			var methodResult = BasicExpressionHelper<ITest>.ObtainMethodAndArguments(x=>x.GetName());
			new DefaultCallBehavior<ITest>(channelAllocator)
			    .InvokeOperation(methodResult.Method, methodResult.Arguments);
		}

		#endregion
	}
}